package com.travel.user.service.impl;

import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
import com.travel.JwtUtils;
import com.travel.RsaUtils;
import com.travel.VerifyCodeUtil;
import com.travel.entity.dto.ResultVO;
import com.travel.sso.TravelUser;
import com.travel.user.mapper.ShoujiMapper;
import com.travel.user.service.ShoujiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.PrivateKey;
import java.util.concurrent.TimeUnit;

public class ShoujiServiceImpl implements ShoujiService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;//模板

    @Autowired
    private ShoujiMapper shoujiMapper;

    public static final String url = "http://gw.api.taobao.com/router/rest";
    public static final	String appkey = "23473071";
    public static final	String secret = "951efdcc9540d2c0c1646ed6d74892e6";

    @Override
    public ResultVO sendCode(String userAccount) {

        if(StringUtils.isEmpty(userAccount))
            return new ResultVO(false,"参数异常");
        TravelUser byPhone = shoujiMapper.findByPhone(userAccount);
        if(byPhone==null) return new ResultVO(false,"注册失败");
        //发送短信,阿里大于短信
        //生成一个4位数的随机验证码
        String code = VerifyCodeUtil.generateVerifyCode(4, "0123456789");


        TaobaoClient client = new DefaultTaobaoClient(url, appkey, secret);
        AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
        req.setExtend("123456");
        req.setSmsType("normal");
        req.setSmsFreeSignName("问道学院");
        req.setSmsParamString("{\"code\":\""+code+"\"}");
        req.setRecNum(userAccount);
        req.setSmsTemplateCode("SMS_209190607");
        AlibabaAliqinFcSmsNumSendResponse rsp = null;
        try {
            rsp = client.execute(req);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        // System.out.println(rsp.getBody());
        //校验
        Boolean success = rsp.getResult().getSuccess();
        if(success){
            //将验证码存放到redis中
            stringRedisTemplate.boundValueOps("sms:"+userAccount).set(code);
            //设置过期时间120s
            stringRedisTemplate.expire("sms:"+userAccount,10, TimeUnit.MINUTES);
            return new ResultVO(false,"发送成功");
        }else {
            return new ResultVO(false,"发送失败");
        }
    }

    @Override
    public ResultVO verifyCode(String userAccount, String code) {
        //根据手机号userAccount从redis中获取验证码
        String redisCode = stringRedisTemplate.boundValueOps("sms:" + userAccount).get();

        if(redisCode==null) return new ResultVO(false,"登陆失败");
        if(!redisCode.equals(code)) return new ResultVO(false,"验证码错误");

        //校验成功后从redis中清除验证码
        stringRedisTemplate.delete("sms:"+userAccount);

        //获取用户信息
        TravelUser userPhone =shoujiMapper.findByPhone(userAccount);
        userPhone.setUserPassword(null);
        //颁发令牌
        PrivateKey privateKey = null;
        try {
            ClassPathResource resource = new ClassPathResource("rsa.pri");
            InputStream inputStream = resource.getInputStream();
            privateKey = RsaUtils.getPrivateKey(readBytes3(inputStream));
        } catch (Exception e) {
            e.printStackTrace();
        }
        String jwtToken = JwtUtils.generateTokenExpireInMinutes(userPhone, privateKey, 30);


        return new ResultVO(true,"登录成功",jwtToken);
    }


    public static byte[] readBytes3(InputStream in) throws IOException {
        BufferedInputStream bufin = new BufferedInputStream(in);
        int buffSize = 1024;
        ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);

        // System.out.println("Available bytes:" + in.available());

        byte[] temp = new byte[buffSize];
        int size = 0;
        while ((size = bufin.read(temp)) != -1) {
            out.write(temp, 0, size);
        }
        bufin.close();

        byte[] content = out.toByteArray();
        return content;
    }

}
